/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file config.c
 * pyhp configuration support
 */

#include "config.h"

extern module pyhp_module;

/**
 * Creates the config entry inside apache and sets up defaults
 */
void * pyhp_make_config(apr_pool_t * p, server_rec *s)
{
    pyhp_config * c = apr_palloc(p, sizeof(pyhp_config));
    c->mode = "development";
    c->log = "apache";
    c->session_path = "/tmp/";
    c->tmp_path = "/tmp/";
    c->log_level = PyHP_DEBUG;
    c->session_timeout = 15;
    c->session_name = "session";
    c->session_backend = PyHPSessionFile;
    c->session_db_uri = "mysql:host=localhost;dbname=pyhp";
    c->session_db_user = "pyhp";
    c->session_db_pass = "pyhp";
    return c;
}

/**
 * Retrieves the config instance from apache
 */
pyhp_config * pyhp_get_config(request_rec * r)
{
    return ap_get_module_config(r->server->module_config, &pyhp_module);
}

/**
 * Checks if the PyHP module is configured in devel mode or not
 * @return 1 = development or not configured, 0 = production
 */
int pyhp_config_isdevel(request_rec *r)
{
    pyhp_config * config = pyhp_get_config(r);
    return (!((config->mode) && (strcmp(config->mode, "production") == 0)));
}

/**
 * Returns the configured logging output
 * @return PyHPLog_Web = send to the browser (default)
 * @return PyHPLog_Apache = write to apache logging
 * @return PyHPLog_None = dont write logging messages
 */
PyHPLogLocation pyhp_config_loglocation(request_rec *r)
{
    pyhp_config * config = pyhp_get_config(r);

    if (!config->log)
        return PyHPLog_Web;
    else if ( strcmp(config->log, "web") == 0 )
        return PyHPLog_Web;
    else if ( strcmp(config->log, "apache") == 0 )
        return PyHPLog_Apache;
    else if ( strcmp(config->log, "none") == 0 )
        return PyHPLog_None;

    return PyHPLog_Web;
}

/**
 * Returns the configured log level
 * @return @see PyHPLogType
 */
PyHPLogType pyhp_config_loglevel(request_rec *r)
{
    pyhp_config * config = pyhp_get_config(r);
    return config->log_level;
}

char *pyhp_loglevel_to_string(PyHPLogType ll, char *output_buffer, int buffer_size)
{
    if (ll == PyHP_DEBUG)
        strncpy(output_buffer, "debug", buffer_size);
    else if (ll == PyHP_INFO)
        strncpy(output_buffer, "info", buffer_size);
    else if (ll == PyHP_WARN)
        strncpy(output_buffer, "warning", buffer_size);
    else if (ll == PyHP_ERR)
        strncpy(output_buffer, "error", buffer_size);
    else
        strncpy(output_buffer, "unknown", buffer_size);

    return output_buffer;
}

/**
 * Returns the configured session timeout
 * @return session timeout in minutes
 */
int pyhp_config_sesstimeout(request_rec *r)
{
    pyhp_config * config = pyhp_get_config(r);
    return config->session_timeout;
}

char *pyhp_sessiontimeout_to_string(int ll, char *output_buffer, int buffer_size)
{
    snprintf(output_buffer, buffer_size, "%d", ll);
    return output_buffer;
}

/**
 * Returns the configured session backend
 * @return @see PyHPSessionType
 */
PyHPSessionType pyhp_config_sessbackend(request_rec *r)
{
    pyhp_config * config = pyhp_get_config(r);
    return config->session_backend;
}

char *pyhp_sessionbackend_to_string(PyHPSessionType ll, char *output_buffer, int buffer_size)
{
    if (ll == PyHPSessionDb)
        strncpy(output_buffer, "db", buffer_size);
    else if (ll == PyHPSessionFile)
        strncpy(output_buffer, "file", buffer_size);
    else
        strncpy(output_buffer, "unknown", buffer_size);

    return output_buffer;
}


/*
 * From here there are the declarators and accessors to the PyHP Configuration
 */


static const char *pyhp_config_set_mode(cmd_parms *parms,
  void *mconfig, const char *arg)
{
    pyhp_config *s_cfg = ap_get_module_config(
    parms->server->module_config, &pyhp_module);

    s_cfg->mode = (char *) arg;

    return NULL;
}

static const char *pyhp_config_set_log(cmd_parms *parms,
  void *mconfig, const char *arg)
{
    pyhp_config *s_cfg = ap_get_module_config(
    parms->server->module_config, &pyhp_module);

    s_cfg->log = (char *) arg;

    return NULL;
}

static const char *pyhp_config_set_log_level(cmd_parms *parms,
  void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg = ap_get_module_config(
    parms->server->module_config, &pyhp_module);

    if (strcasecmp(arg, "debug") == 0)
        s_cfg->log_level = PyHP_DEBUG;
    else if (strcasecmp(arg, "info") == 0)
        s_cfg->log_level = PyHP_INFO;
    else if (strcasecmp(arg, "warning") == 0)
        s_cfg->log_level = PyHP_WARN;
    else if (strcasecmp(arg, "error") == 0)
        s_cfg->log_level = PyHP_ERR;
    else
        s_cfg->log_level = PyHP_ERR;

    return NULL;
}

static const char *pyhp_config_set_session_path(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    s_cfg->session_path = (char *) arg;

    return NULL;
}

static const char *pyhp_config_set_temporary_path(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    s_cfg->tmp_path = (char *) arg;

    return NULL;
}

static const char *pyhp_config_set_session_timeout(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    s_cfg->session_timeout = atoi((char *)arg);

    return NULL;
}

static const char *pyhp_config_set_session_name(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    s_cfg->session_name = (char *) arg;

    return NULL;
}

static const char *pyhp_config_set_session_backend(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    if (strcasecmp(arg, "db") == 0)
        s_cfg->session_backend = PyHPSessionDb;
    else
        s_cfg->session_backend = PyHPSessionFile;

    return NULL;
}

static const char *pyhp_config_set_session_db_uri(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    s_cfg->session_db_uri = (char *) arg;

    return NULL;
}

static const char *pyhp_config_set_session_db_user(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    s_cfg->session_db_user = (char *) arg;

    return NULL;
}

static const char *pyhp_config_set_session_db_pass(cmd_parms *parms,
                                                void *mconfig, const char *arg)
{
    int level = 0;

    pyhp_config *s_cfg =
        ap_get_module_config(parms->server->module_config, &pyhp_module);

    s_cfg->session_db_pass = (char *) arg;

    return NULL;
}

const command_rec pyhp_options[] =
{
  AP_INIT_TAKE1(
    "PyHPMode",
    pyhp_config_set_mode,
    NULL,
    RSRC_CONF,
    "development/production (string) The execution mode."
  ),
  AP_INIT_TAKE1(
    "PyHPLog",
    pyhp_config_set_log,
    NULL,
    RSRC_CONF,
    "apache/web/none (string) Where to write logging"
  ),
  AP_INIT_TAKE1(
    "PyHPLogLevel",
    pyhp_config_set_log_level,
    NULL,
    RSRC_CONF,
    "debug/info/warning/error (string) Minimum message level to be reported"
  ),
  AP_INIT_TAKE1(
    "PyHPSessionPath",
    pyhp_config_set_session_path,
    NULL,
    RSRC_CONF,
    "path to the session Path (string) in which store the session files"
  ),
  AP_INIT_TAKE1(
    "PyHPTempPath",
    pyhp_config_set_temporary_path,
    NULL,
    RSRC_CONF,
    "path to the temporary Path (string) in which store the uploaded files"
  ),
  AP_INIT_TAKE1(
    "PyHPSessionTimeout",
    pyhp_config_set_session_timeout,
    NULL,
    RSRC_CONF,
    "timeout of the pyhp session in minutes"
  ),
  AP_INIT_TAKE1(
    "PyHPSessionName",
    pyhp_config_set_session_name,
    NULL,
    RSRC_CONF,
    "name of the session cookie"
  ),
  AP_INIT_TAKE1(
    "PyHPSessionBackend",
    pyhp_config_set_session_backend,
    NULL,
    RSRC_CONF,
    "session saving backend"
  ),
  AP_INIT_TAKE1(
    "PyHPDbSessionUri",
    pyhp_config_set_session_db_uri,
    NULL,
    RSRC_CONF,
    "database uri when saving sessions on db"
  ),
  AP_INIT_TAKE1(
    "PyHPDbSessionUser",
    pyhp_config_set_session_db_user,
    NULL,
    RSRC_CONF,
    "database user when saving sessions on db"
  ),
  AP_INIT_TAKE1(
    "PyHPDbSessionPass",
    pyhp_config_set_session_db_pass,
    NULL,
    RSRC_CONF,
    "database password when saving sessions on db"
  ),
  {NULL}
};

